/*
 * Copyright (C) 2014 Francisco José Morero Peyrona. All Rights Reserved.
 *
 * This file is part of JStatViewer project: https://code.google.com/p/jstat-viewer/
 *
 * GNU Classpath is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the free
 * Software Foundation; either version 3, or (at your option) any later version.
 *
 * Tapas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * Tapas; see the file COPYING.  If not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package jstatviewer.reader;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * A data structure that stores column names and values per column.
 *
 * @author peyrona
 */
public class JStats
{
    private int nLinesWithError = 0;
    private String[] colNamesTmp = new String[0];     // Last column names found
    private final Map<String,List<Double>> columns = new HashMap<>();

    //----------------------------------------------------------------------------//

    /**
     * Protected constructor: only JStatFileReader can instantiate this class.
     */
    JStats()
    {
    }

    //----------------------------------------------------------------------------//

    public List<String> getColumnNames()
    {
        List<String> names = new ArrayList<>();

        for( Map.Entry<String,List<Double>> entry : columns.entrySet() )
        {
            if( ! entry.getValue().isEmpty() )
            {
                names.add( entry.getKey() );
            }
        }

        return names;
    }

    public List<Double> getValuesFor( String sColumnName )
    {
        return columns.get( sColumnName );
    }

    public void setColumnNames( String... colNames )
    {
        assert colNames == null     : "Column names array can't be null";
        assert colNames.length == 0 : "Column names array can't be empty";

        // Defensive copy
        colNamesTmp = new String[ colNames.length ];
        System.arraycopy( colNames, 0, colNamesTmp, 0, colNames.length );

        // Add to Map those columns that do not exist
        for( String name : colNames )
        {
            if( ! columns.containsKey( name ) )
            {
                columns.put( name, new LinkedList<Double>() );
            }
        }
    }

    public int getLinesNotProcessed()
    {
        return nLinesWithError;
    }

    public void add( int colIndex, double colValue )
    {
        // Es enrebesado obtener la lista de valores por su posición ordinal pq
        // los elementos de los Maps no están almacenados secuencialmente y además
        // pueden (bajo ciertas curcunstancias) variar su posición (índice).
        // Asi que hay que buscar la lista de valores a través de su nombre en el Map.

        if( colIndex >= 0 && colIndex < colNamesTmp.length )
        {
            String       colName = colNamesTmp[ colIndex ];
            List<Double> lstVals = getListOfValues4Name( colName );

            lstVals.add( colValue );
        }
        else
        {
            nLinesWithError++;
        }
    }

    //----------------------------------------------------------------------------//

    private List getListOfValues4Name( String colName )
    {
        for( Map.Entry<String,List<Double>> entry : columns.entrySet() )
        {
            if( entry.getKey().equals( colName ) )
            {
                return entry.getValue();
            }
        }

        return null;
    }
}